<template>
  <div :class="[!border ? 'no-border' : '']"
       class="city-select">
    <div :class="{show: showValue}"
         class="select"
         @click="showClick">
      <template v-for="addr in address"
                v-if="address?.length">{{ addr.name + ' ' }}
      </template>
      <div class="placeholder" v-else>请选择收货地址</div>
      <i class="iconfont icon-angle-down"/>
    </div>
    <div :class="{show: showValue}"
         class="value">
      <div v-for="city in subCities"
           :key="city.code">
        <span :title="city.name"
              class="ellipsis"
              @click="address.push(city)">
          {{ city.name }}
        </span>
      </div>
    </div>
  </div>
</template>

<script lang="ts"
        setup>
import {getCity} from '@/api/good'
import type {City} from '@/types/city'
import type {Ref} from 'vue'
import {computed, inject, onMounted, ref, watch} from 'vue'

withDefaults(defineProps<{
  border?: boolean
}>(), {
  border: true
})

onMounted(() => {
  initCity()
})

let showValue = ref<boolean>(false)
let address = inject<Ref<City[]>>('address')

function showClick() {
  showValue.value = !showValue.value
  address && (address.value = [])
}


let cities = ref<City[]>([])

async function initCity(): Promise<void> {
  // 如果sessionStorage有，则重用
  let _cities = sessionStorage.getItem('city')
  if (_cities) {
    cities.value = JSON.parse(_cities)
    return
  }
  let res = <any>await getCity()
  cities.value = <City[]>res
  sessionStorage.setItem('city', JSON.stringify(cities.value))
}

let subCities = computed((): City[] => {
  if (address?.value.length) {
    let city: City | null = dfsFindCity(cities.value, address.value[address.value.length - 1].code ?? 0)
    return city?.areaList ?? []
  }
  return cities.value
})

watch(() => subCities.value, (v) => {
  if (!v.length)
    showValue.value = false
})

function dfsFindCity(cities: City[], code: number): City | null {
  for (let city of cities) {
    if (city.code === code)
      return city
    if (city.areaList?.length) {
      let _city: City | null = dfsFindCity(city.areaList, code)
      if (_city)
        return _city
    }
  }
  return null
}
</script>

<style lang="less"
       scoped>
.city-select {
  position: relative;
  border: 1px solid #e4e4e4;
  cursor: pointer;
  height: 30px;
  display: flex;
  align-items: center;

  &.no-border {
    border: none;
    width: 100%;
    height: 100%;
  }

  .select {
    width: 100%;
    display: flex;
    padding: 0 10px;
    justify-content: space-between;
    align-items: center;

    &.show {
      border-bottom: none;
    }

    .placeholder {
      color: #cccccc;
    }

    i {
      transform: translateY(1px);
      padding-left: 10px;
      font-size: 12px;
    }
  }

  .value {
    display: none;
    border: 1px solid #e4e4e4;
    padding: 10px;
    position: absolute;
    flex-wrap: wrap;
    top: 100%;
    left: 0;
    width: 542px;
    background-color: white;

    &.show {
      display: flex;
    }

    div {
      width: 130px;
      padding: 0 20px;
      height: 30px;
      display: flex;
      justify-content: center;
      align-items: center;
      cursor: pointer;
      overflow: hidden;
    }
  }
}
</style>